package com.example.dps;

import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;

import android.app.AlarmManager;
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;



public class AddMoneyService extends IntentService{
	
	private static final int PI_REQ_CODE = 2;
	private static final int NOTIFICATION_CODE = -1;
	private static final int TRANSFER_CODE = 4;

	public AddMoneyService() {
		super("AddMoneyService");
		// TODO Auto-generated constructor stub
	}

	boolean autoTransferEnabled = false;
	String reminderFrequency = "none";
	
	
	

	DBHelper dbHelper;
	TransferDBHelper transferDBHelper;
	
	String tag="DownPaymentSaverService";
	
	/** enabled notifications **/
	boolean enableNotifications = false;
	
	
	@Override
	protected void onHandleIntent(Intent intent) {
		// TODO Auto-generated method stub
		
		this.dbHelper = new DBHelper(this);
		this.transferDBHelper = new TransferDBHelper(this);
		
		//get the preferences from the settings menu
		getPreferences();

		
		setAlarmService();
		
		
		
		
	}


	
	
	/** 
	 * sets the next alarm
	 * either a notification or a transfer
	 * @param code
	 */
	public void setAlarmService(){

		//int daysToReminder = this.getDaysTilReminder();
		
		//int daysToDeposit = this.getDaysTilDeposit();
		
		//getPreferences();
		
		removeEndingTransfers();
		
		
		if(this.enableNotifications == true){
			/** create notification and add to alarm manager **/
			scheduleNotification();
		}
		else{
			/** remove the notification from the alarm manager **/
			removeNotification();
		}
		
		if(this.autoTransferEnabled == true){
			/** create all the auto transfers, add to alarm manager **/
			scheduleAllTransfers();
		}
		else{
			/** else auto-transfers disabled, remove them from alarm manager **/
			removeAllTransfers();
		}

		



	}
	
	public void removeAllTransfers() {
		
		Transfer[] transfers = transferDBHelper.getTransfersAsTransfer();
		
		for(Transfer transfer : transfers){
			
			removeTransfer(transfer.id);
			
		}
		
	}


	/**
	 *  schedule the next transfer
	 * 
	 */
	public void scheduleTransfer(){
		/** get the days until the next auto transfer **/
	
		Transfer nextTransfer = null;
		try {
			nextTransfer = this.transferDBHelper.getNextTransfer();
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	
		if(nextTransfer != null){
			Intent intent = new Intent(AddMoneyService.this, AlarmReceiver.class);
			intent.putExtra("isTransfer", true);
			intent.putExtra("transferID", nextTransfer.id);
	        PendingIntent sender = PendingIntent.getBroadcast(AddMoneyService.this,
	                nextTransfer.id, intent, 0);

	        
	        Calendar calendar = Calendar.getInstance();
	        calendar.setTime(nextTransfer.nextTransfer);

	        // Schedule the alarm!
	        AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
	        am.set(AlarmManager.RTC, calendar.getTimeInMillis(), sender);

		}
		

	}
	
	
	/** schedule the next notification **/
	public void createNotification(){
		
		if(this.enableNotifications){
			
			
			SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
			
			Date now = new Date();
			Date lastDeposit = this.dbHelper.getLastDeposit();
			Date lastRemindedDate = this.dbHelper.getLastReminded();
			
			Calendar calendar = Calendar.getInstance();
			
			String freqString = prefs.getString("notificationFrequencyPref", "30");
			int interval = 0;
			try{
				interval = Integer.parseInt(freqString);
			}
			catch(NumberFormatException e){
				interval = 30;
			}
			
			
			
			if(lastDeposit == null && lastRemindedDate == null){
				/** if no deposit, no reminder; schedule notification for now + interval **/
				calendar.setTime(new Date());
				calendar.add(Calendar.DAY_OF_YEAR, interval);
			}
			else if(lastDeposit == null && lastRemindedDate != null){
				/** if reminded but never deposited, schedule notification for lastReminded + interval **/
				calendar.setTime(lastRemindedDate);
				calendar.add(Calendar.DAY_OF_YEAR, interval);	
			}
			else if(lastDeposit != null && lastRemindedDate == null){
				/** if not ever reminded, but deposited, schedule lastDeposit + interval **/
				calendar.setTime(lastDeposit);
				calendar.add(Calendar.DAY_OF_YEAR, interval);
			}
			else if(lastRemindedDate.after(lastDeposit)){
				/** if last reminded is after last deposit date, schedule next notification to interval + last Reminded Date **/
				calendar.setTime(lastRemindedDate);
				calendar.add(Calendar.DAY_OF_YEAR, interval);

			}
			else if(lastDeposit.after(lastRemindedDate)){
				/** if deposited after reminder, schedule reminder for lastDeposit + interval **/
				calendar.setTime(lastDeposit);
				calendar.add(Calendar.DAY_OF_YEAR, interval);
				
			}
			else{
				/** last reminder, last deposit the same: schedule + interval **/
				calendar.setTime(lastDeposit);
				calendar.add(Calendar.DAY_OF_YEAR, interval);
				
			}
			int daysSinceDeposit = 0;
			if(lastDeposit == null) {
				daysSinceDeposit = -1;
			}
			else {
				daysSinceDeposit = (int) ((now.getTime() - lastDeposit.getTime())/(1000*60*60*24));
			}
			
			Log.e(tag, "Days Since Deposit = " + daysSinceDeposit);
			
			/** schedule the notification **/
			Intent intent = new Intent(AddMoneyService.this, AlarmReceiver.class);
			intent.putExtra("isTransfer", false);
			intent.putExtra("daysSinceDeposit", daysSinceDeposit);
	        PendingIntent sender = PendingIntent.getBroadcast(AddMoneyService.this,
	                NOTIFICATION_CODE, intent, 0);

	        

	        // Schedule the alarm!
	        AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
	        am.set(AlarmManager.RTC, calendar.getTimeInMillis(), sender);
				
		}

	}
	
	
	public void createDepositReminder(int daysSinceDeposit){
		
		

		
		
		
	}


	/** returns the number of days until the next reminder should be launched **/
	public int getDaysTilReminder(){
		
		Date lastDeposit = this.dbHelper.getLastDeposit();
		
		Log.e("service" , lastDeposit.toLocaleString());
		
		Date now = new Date();
		
		int daysSinceDeposit = (int) ((now.getTime() - lastDeposit.getTime())/(1000*60*60*24));
		
		int yearDays = 365;
		int halfYearDays = 182;
		int monthDays = 30;
		int halfMonthDays = 15;
		int weekDays = 7;
		
		Log.e("days " , "days since deposit = " + daysSinceDeposit);
		
		if(this.reminderFrequency.equals("weekly") && daysSinceDeposit <= weekDays){
			//createDepositReminder(daysSinceDeposit);
			return weekDays-daysSinceDeposit;
		}
		else if(this.reminderFrequency.equals("bimonthly") && daysSinceDeposit <= halfMonthDays){
			//createDepositReminder(daysSinceDeposit);
			return halfMonthDays-daysSinceDeposit;
		}
		else if(this.reminderFrequency.equals("monthly") && daysSinceDeposit <= monthDays){
			//createDepositReminder(daysSinceDeposit);
			return monthDays-daysSinceDeposit;
		}
		else if(this.reminderFrequency.equals("half-yearly") && daysSinceDeposit <= halfYearDays){
			//createDepositReminder(daysSinceDeposit);
			return halfYearDays-daysSinceDeposit;
		}
		else if(this.reminderFrequency.equals("yearly") && daysSinceDeposit <= yearDays){
			//createDepositReminder(daysSinceDeposit);
			return yearDays-daysSinceDeposit;
		}

		
		return -1;
		
	}
	
	
	public Date getNextReminderDate(){
		
		Date lastDeposit = this.dbHelper.getLastDeposit();
		
		Log.e("service" , lastDeposit.toLocaleString());

		
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(lastDeposit);
		
		
		int yearDays = 365;
		int halfYearDays = 182;
		int monthDays = 30;
		int halfMonthDays = 15;
		int weekDays = 7;
		
		int interval = 0;
		
		
		if(this.reminderFrequency.equals("weekly")){
			interval = weekDays;
		}
		else if(this.reminderFrequency.equals("bimonthly")){
			interval = halfMonthDays;
		}
		else if(this.reminderFrequency.equals("monthly")){
			//createDepositReminder(daysSinceDeposit);
			interval = monthDays;
		}
		else if(this.reminderFrequency.equals("half-yearly")){
			//createDepositReminder(daysSinceDeposit);
			interval = halfYearDays;
		}
		else if(this.reminderFrequency.equals("yearly")){
			//createDepositReminder(daysSinceDeposit);
			interval = yearDays;
		}
		else if(this.reminderFrequency.equals("daily")){
			interval = 1;
		}
		else return null;

		/** add interval to calendar to get next reminder date **/
		calendar.add(Calendar.DAY_OF_YEAR, interval);
		return calendar.getTime();
		
	}
	
	public void getPreferences(){
		
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
		
		this.autoTransferEnabled = prefs.getBoolean("autoTransferPref", false);
		this.reminderFrequency = prefs.getString("notificationFrequencyPref", "daily").toLowerCase();
		this.enableNotifications = prefs.getBoolean("enableNotificationsPref", false);
		
		if(autoTransferEnabled) Log.e(tag, "Auto Transfers Enabled!");
		if(enableNotifications) Log.e(tag, "Notifications Enabled");
		
		Log.e(tag, "reminder Freq = " + this.reminderFrequency);
		
	}
	
	/**
	 * get the days until the next auto-transfer
	 * @return the days until the next auto-transfer
	 */
	public int getDaysTilDeposit(){
		
		int tid = 0;
		Transfer nextTransfer = null;
		
		/** get the next occuring transfer in transfer DB **/
		try {
			nextTransfer = transferDBHelper.getNextTransfer();
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		if(nextTransfer != null){
			
			
			
			Log.e(tag, "nextTransfer Date = " + nextTransfer.nextTransfer);
			
			Date now = new Date();
			
			int daysTilDeposit = (int) ((now.getTime() - nextTransfer.nextTransfer.getTime())/(1000*60*60*24));
			
			return daysTilDeposit;
			
			
		}
		
		return -1;
		
	}
	
	/**
	 * schedule the next notificiation only
	 */
	public void scheduleNotification(){
		
		createNotification();
		
	}
	
	
	
	
	/**
	 * remove the alarm for this intent
	 */
	public void removeTransfer(int transferID){
		
		Log.e(tag, "Removing Transfer");
		Intent intent = new Intent(AddMoneyService.this, AlarmReceiver.class);
        PendingIntent sender = PendingIntent.getBroadcast(AddMoneyService.this,
                transferID, intent, 0);


        // Schedule the alarm!
        AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
        am.cancel(sender);
	    
	}
	
	public void removeNotification(){
		Log.e(tag, "Removing Notification");
		Intent intent = new Intent(AddMoneyService.this, AlarmReceiver.class);
        PendingIntent sender = PendingIntent.getBroadcast(AddMoneyService.this,
        		NOTIFICATION_CODE, intent, 0);


        // Schedule the alarm!
        AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
        am.cancel(sender);
		
	}
	
	
	public void scheduleAllTransfers(){
		
		
		Log.e(tag, "SCHEDULING ALL TRANSFERS *******");
	
		for(Transfer transfer : transferDBHelper.getTransfersAsTransfer()){
		

			Log.e(tag, "nextTransfer = " + transfer.nextTransfer.toLocaleString());
			Log.e(tag, "Date() = " + new Date().toLocaleString());
			Log.e(tag, "transfer id = " + transfer.id);
			
			/** if transfer is enabled, schedule it **/
			if(transfer.enabled){
				Intent intent = new Intent(AddMoneyService.this, AlarmReceiver.class);
				intent.putExtra("isTransfer", true);
				intent.putExtra("transferID", transfer.id);
		        PendingIntent sender = PendingIntent.getBroadcast(AddMoneyService.this,
		                transfer.id, intent, 0);
		
		        
		        Calendar calendar = Calendar.getInstance();
		        calendar.setTime(transfer.nextTransfer);
		
		        // Schedule the alarm!
		        AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
		        am.set(AlarmManager.RTC, calendar.getTimeInMillis(), sender);
			}
			else{
				/** if disabled, remove it from alarm manager **/
				Intent intent = new Intent(AddMoneyService.this, AlarmReceiver.class);
				intent.putExtra("isTransfer", true);
				intent.putExtra("transferID", transfer.id);
		        PendingIntent sender = PendingIntent.getBroadcast(AddMoneyService.this,
		                transfer.id, intent, 0);

		
		        // Schedule the alarm!
		        AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
		        am.cancel(sender);
				
				
			}
			
	        
		}
				
		
	}
	
	

	/** delete transfers from DB if they have passed their ending date **/
	public void removeEndingTransfers(){
		
		Transfer[] transfers = this.transferDBHelper.getTransfersAsTransfer();
		
		for(Transfer transfer : transfers){
			
			if(transfer.ending.before(new Date())){
				Log.e(tag, "transfer ended!");
				transfer.removeFromDatabase(this.transferDBHelper);
			}
			
		}
		
	}



}
